<template>
  <div class="websocket">
    <div class="status">
      <span class="status-indicator" :class="{ active: isConnected }"></span>
      <span class="status-text">{{ isConnected ? '✅ 已连接' : '❌ 未连接' }}</span>
      <span class="online-count">在线人数：{{ onlineCount }}</span>
    </div>

    <!-- 消息列表 -->
    <div class="message-box">
      <h3>消息记录：</h3>
      <div class="message-list" ref="messageListRef">
        <div 
          v-for="(msg, index) in messageList" 
          :key="index" 
          class="message-item"
          :class="{ 
            'system-message': msg.from === '系统' || msg.from === '服务器',
            'new-message': index === messageList.length - 1 && isConnected
          }"
        >
          <span class="time">{{ msg.time }}</span>
          <span class="from">{{ msg.from }}：</span>
          <span class="content">{{ msg.content }}</span>
        </div>
        <div v-if="messageList.length === 0" class="empty-message">
          等待连接...
        </div>
      </div>
    </div>

    <!-- 发送消息表单 -->
    <div class="send-form">
      <input
        v-model="inputContent"
        placeholder="输入消息..."
        @keyup.enter="sendMessage"
        :disabled="!isConnected"
        class="message-input"
      />
      <button 
        @click="sendMessage" 
        :disabled="!isConnected || !inputContent.trim()"
        class="send-btn"
      >
        发送
      </button>
    </div>
    
    <div class="stats">
      <div class="stat-item">
        <span class="stat-label">消息总数：</span>
        <span class="stat-value">{{ messageList.length }}</span>
      </div>
      <div class="stat-item">
        <span class="stat-label">连接状态：</span>
        <span class="stat-value" :class="{ connected: isConnected }">
          {{ isConnected ? '已连接' : '未连接' }}
        </span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onUnmounted, nextTick } from 'vue'
import { io } from 'socket.io-client'

const isConnected = ref(false)
const onlineCount = ref(0)
const inputContent = ref('')
const messageList = ref([])
const messageListRef = ref(null)
let socket = null

// 连接 WebSocket
const connectWebSocket = () => {
  // 连接后端 WebSocket 服务
  socket = io('http://localhost:3000', {
    transports: ['websocket', 'polling'],
    autoConnect: true,
  })

  // 连接成功
  socket.on('connect', () => {
    isConnected.value = true
    messageList.value.push({
      from: '系统',
      content: '已成功连接 WebSocket',
      time: new Date().toLocaleTimeString(),
    })
    scrollToBottom()
  })

  // 连接失败
  socket.on('connect_error', (error) => {
    console.error('WebSocket 连接失败：', error)
    isConnected.value = false
    messageList.value.push({
      from: '系统',
      content: 'WebSocket 连接失败，请重试',
      time: new Date().toLocaleTimeString(),
    })
  })

  // 断开连接
  socket.on('disconnect', () => {
    isConnected.value = false
    messageList.value.push({
      from: '系统',
      content: 'WebSocket 已断开连接',
      time: new Date().toLocaleTimeString(),
    })
  })

  // 监听欢迎消息
  socket.on('welcome', (data) => {
    messageList.value.push({
      from: '系统',
      content: data.message,
      time: new Date().toLocaleTimeString(),
    })
    scrollToBottom()
  })

  // 监听在线人数更新
  socket.on('onlineCount', (data) => {
    onlineCount.value = data.count
  })

  // 监听新消息
  socket.on('newMessage', (data) => {
    messageList.value.push(data)
    scrollToBottom()
  })

  // 监听服务器定时推送
  socket.on('serverPush', (data) => {
    messageList.value.push({
      from: '服务器',
      content: data.message,
      time: new Date().toLocaleTimeString(),
    })
    scrollToBottom()
  })
}

// 发送消息
const sendMessage = () => {
  if (!inputContent.value.trim() || !isConnected.value) return
  
  // 向服务器发送「sendMessage」事件
  socket?.emit('sendMessage', { content: inputContent.value.trim() })
  
  // 清空输入框
  inputContent.value = ''
}

// 滚动到最新消息
const scrollToBottom = () => {
  nextTick(() => {
    if (messageListRef.value) {
      messageListRef.value.scrollTop = messageListRef.value.scrollHeight
    }
  })
}

// 组件挂载时连接
connectWebSocket()

// 组件卸载时断开连接
onUnmounted(() => {
  socket?.disconnect()
})
</script>

<style scoped>
.websocket {
  padding: 0;
}

.status {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
  padding: 12px;
  background: #f8f9fa;
  border-radius: 8px;
  border-left: 4px solid #6f42c1;
}

.status-indicator {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #dc3545;
  transition: background-color 0.3s ease;
}

.status-indicator.active {
  background: #6f42c1;
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0% { opacity: 1; }
  50% { opacity: 0.5; }
  100% { opacity: 1; }
}

.status-text {
  font-weight: 500;
  color: #2c3e50;
}

.online-count {
  margin-left: auto;
  font-size: 0.85rem;
  color: #666;
}

.message-box {
  margin: 20px 0;
  padding: 20px;
  background: #fff;
  border: 2px solid #e9ecef;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}

.message-box h3 {
  color: #2c3e50;
  margin-bottom: 12px;
  font-size: 1.1rem;
}

.message-list {
  max-height: 300px;
  overflow-y: auto;
  padding: 8px;
  background: #f8f9fa;
  border-radius: 8px;
}

.message-item {
  margin: 8px 0;
  padding: 8px 12px;
  background: #fff;
  border-radius: 6px;
  border-left: 3px solid #6f42c1;
  font-size: 0.9rem;
  line-height: 1.4;
  transition: all 0.3s ease;
}

.message-item.system-message {
  background: #f8f9fa;
  border-left-color: #6c757d;
  font-style: italic;
}

.message-item.new-message {
  background: #e8e2ff;
  border-left-color: #6f42c1;
  animation: highlight 1s ease-out;
}

@keyframes highlight {
  0% { background: #d1c4e9; }
  100% { background: #e8e2ff; }
}

.time {
  color: #999;
  font-size: 0.75rem;
  margin-right: 8px;
}

.from {
  font-weight: bold;
  margin-right: 8px;
  color: #6f42c1;
}

.content {
  color: #495057;
}

.empty-message {
  text-align: center;
  color: #6c757d;
  font-style: italic;
  padding: 20px;
}

.send-form {
  display: flex;
  gap: 12px;
  margin: 20px 0;
}

.message-input {
  flex: 1;
  padding: 12px 16px;
  border: 2px solid #e9ecef;
  border-radius: 8px;
  font-size: 1rem;
  transition: border-color 0.3s ease;
}

.message-input:focus {
  outline: none;
  border-color: #6f42c1;
}

.message-input:disabled {
  background: #f8f9fa;
  cursor: not-allowed;
}

.send-btn {
  padding: 12px 24px;
  font-size: 1rem;
  font-weight: 500;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  background: #6f42c1;
  color: white;
  min-width: 80px;
}

.send-btn:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(111, 66, 193, 0.3);
}

.send-btn:disabled {
  background: #6c757d;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 20px;
  padding: 16px;
  background: #f8f9fa;
  border-radius: 8px;
}

.stat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.stat-label {
  font-size: 0.85rem;
  color: #6c757d;
  margin-bottom: 4px;
}

.stat-value {
  font-size: 1.1rem;
  font-weight: 600;
  color: #2c3e50;
}

.stat-value.connected {
  color: #6f42c1;
}

@media (max-width: 480px) {
  .stats {
    grid-template-columns: 1fr;
  }
  
  .status {
    flex-wrap: wrap;
    gap: 8px;
  }
  
  .online-count {
    margin-left: 0;
  }
  
  .send-form {
    flex-direction: column;
  }
}
</style> 